﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using IM.Interfaces.GUI;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using Common.Interfaces;

namespace IM.GUI.Conversation
{
	
	internal class ConversationBrowserFactory : IControlFactory
	{
		#region IControlFactory implementation
		public Control Create ()
		{
			ConversationBrowser browser = new ConversationBrowser();
			browser.Dock = DockStyle.Fill;
			return browser;
		}
		
		#endregion
	}
	
	/// <summary>
	/// actual control that contains the conversation 
	/// </summary>
    public class ConversationBrowser : UserControl, IConversationBrowser
    {
        public enum MessageDirection { IncomingMessage, OutgoingMessage }

        WebBrowser webBrowser = new WebBrowser();

        ManualResetEvent documentCompleted = new ManualResetEvent(false);

        public ConversationBrowser()
        {
            InitWebBrowser();
        }

        private String GetContentOfFile(String path)
        {
            using (StreamReader f = File.OpenText(path))
            {
                return f.ReadToEnd();
            }
        }

        private String GetStylesString(String path)
        {
            String styles = GetContentOfFile(path);

            return String.Format("<style type='text/css'>{0}</style>", styles);
        }

        private String GetJavascriptString(String path)
        {
            String js = GetContentOfFile(path);

            return String.Format("<script language='javascript'>{0}</script>", js);
        }

        private String GetHTMLTemplate()
        {
            String template = GetContentOfFile("Themes/Conversations/template.ivt");
            template = template.Replace("%base%", "Themes/Conversations/");

            Regex jsRegEx = new Regex("<script.+src=\"(.+)\"></script>");
            Regex styleRegEx = new Regex("<link.+href=\"(.+)\"></style>");

            MatchCollection matches = jsRegEx.Matches(template);
            Match styleMatch = styleRegEx.Match(template);

            if (styleMatch.Success)
            {
                string text = styleMatch.Groups[0].Value;
                int index = template.IndexOf(text);
                template = template.Replace(text, String.Empty);
                template = template.Insert(index, GetStylesString(styleMatch.Groups[1].Value));
            }

            foreach (Match m in matches)
            {
                string text = m.Groups[0].Value;

                int index = template.IndexOf(text);
                template = template.Replace(text, String.Empty);
                template = template.Insert(index, GetJavascriptString(m.Groups[1].Value));
            }

            return template;
        }

        private void InitWebBrowser()
        {
            documentCompleted.Reset();
            webBrowser.Dock = DockStyle.Fill;
            this.Controls.Add(webBrowser);
            webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
            webBrowser.DocumentText = GetHTMLTemplate();
            Application.DoEvents();
            webBrowser.Navigating += new WebBrowserNavigatingEventHandler(webBrowser_Navigating);
        }

        void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            e.Cancel = true;

            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = e.Url.ToString();
            p.Start();
        }

        void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            documentCompleted.Set();
        }

        private HtmlElement CreateMessage(String username, String message, String time, MessageDirection direction)
        {
            if (message.Contains("http://"))
            {
                int index1 = message.IndexOf("http://");
                String link = message.Substring(index1);
                index1 = link.IndexOf(" ");

                if (index1 > 0)
                    link = link.Substring(0, index1);

                message = String.Format("<a href='{0}'>{1}</a>", link, message);
            }

            HtmlElement messageElement = this.webBrowser.Document.CreateElement("div");
            HtmlElement headElement = this.webBrowser.Document.CreateElement("div");
            HtmlElement bodyElement = this.webBrowser.Document.CreateElement("div");

            messageElement.SetAttribute("id", "box");

            bodyElement.SetAttribute("id", "toBeAnalyzed");

            if (direction == MessageDirection.IncomingMessage)
                headElement.SetAttribute("id", "in-head");
            else
                headElement.SetAttribute("id", "out-head");

            headElement.InnerHtml = String.Format("{0}<span class='timestamp'>{1}</span>", username, time);
            bodyElement.InnerHtml = message;
            messageElement.AppendChild(headElement);
            messageElement.AppendChild(bodyElement);

            return messageElement;
        }

        public void AddIncomingMessage(string username, string message, string time)
        {
            if (String.IsNullOrEmpty(message))
                return;

            documentCompleted.WaitOne();
            webBrowser.Document.Body.AppendChild(CreateMessage(username, message, time, MessageDirection.IncomingMessage));
            Object obj = webBrowser.Document.InvokeScript("startEmbeding");
            this.webBrowser.Document.Body.ScrollTop += 1000000;
        }

        public void AddOutgoingMessage(string username, string message, string time)
        {
            if (String.IsNullOrEmpty(message))
                return;

            documentCompleted.WaitOne();
            webBrowser.Document.Body.AppendChild(CreateMessage(username, message, time, MessageDirection.OutgoingMessage));
            Object obj = webBrowser.Document.InvokeScript("startEmbeding");
            this.webBrowser.Document.Body.ScrollTop += 1000000;
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // ConversationBrowser
            // 
            this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
            this.Name = "ConversationBrowser";
            this.ResumeLayout(false);

        }
    }
}
